//////////////////////////////////////////////////////////////////////////
//
// Globant Cpp Training 1
//
// Flow Control:
//    - Selection Statements
//    - Function Calls
//    - Iteration Statements
//    - Operator Precedence
//
//////////////////////////////////////////////////////////////////////////

#include <iostream>

/////////////////////////////////////////////////////*//////////////////////
// Question: What value gets printed by the program?
/*
int main(int argc, char** argv)
{
    int x;

    x = 1, 2, 3;

    std::cout << x << std::endl;
}
*/
// Answer: 1
// Description: The operands to the comma operator are evaluated from 
// left to right. The value of the left hand expression is discarded. 
// The type and value of the result are the type type and value of 
// the right hand operand. Note: assignment takes precedence over the comma operator, 
// so in this case x=1 is evaluated first; than x, 2, 3
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed by the program?
/*
int main() 
{ 
    int x = 3;

    switch(x) {
    case 0:
        {
            int x = 1;
            std::cout << x << std::endl;
        }
        break;
    case 3:
        std::cout << x << std::endl;
        break;
    default:
        x = 2;
        std::cout << x << std::endl;
    }
} */
// Answer: nothing, it is ill-formed
// Description: Jumping into a block and bypassing a declaration with 
// an initialization is ill-formed. In this example there are cases 
// which would bypass the declaration and initialization of block 
// scope x declaration.
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed by the program?
/*
int foo(int y);
int foo(int x)
{
    return x + 1;
}

int main(int argc, char** argv)
{
    int x = 3;
    int y = 6;

    std::cout << foo(x) << std::endl;
}*/
// Answer: 4
// Description: The trick here is, we change the parameter names from 
// the function declaration to function definition. This is legal, 
// and only the parameter names in the function definition are used.
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed by the program?
/*
int main() 
{
    int intArray[2] = { 10, 100 };
    int* p = intArray;
        
    std::cout << *p++ << std::endl; 
}*/
// Answer: 10
// Description: *p++ means *(p++) because * and ++ are unary operators
// so they are right-associative
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What happens in the following example?
/*
int main() 
{
    int intArray[2] = {0, 1};
    int i = 1;
    intArray[i] = i++;
}*/
// Answer: Undefined
// Description: May be evaluated as either intArray[1] = 1, 
// intArray[2] = 1 or may cause some even stranger behavior.
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed by the program?
/*
struct Foo {
    int mMember; 
};
int main() {
    Foo* foo = new Foo;
    foo->mMember = 10;
    foo = 0;

    if (foo && foo->mMember == 10) {
        std::cout << "SUCCESS" << std::endl;
    } else {
        std::cout << "FAILURE" << std::endl;
    }
}*/
// Answer: FAILURE
// Description: The first statement is zero because foo is NULL, 
// so the second statement is not executed and the condition is false
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What is printed by the program?
/*
int main() {
    int value = 0;

    switch (value++) {
    case 0:
        std::cout << "case 0" << std::endl;
    case 1:
        std::cout << "case 1" << std::endl;
    default:
        std::cout << "default" << std::endl;
    }
}*/
// Answer: case 0 case 1 default
// Description: Beware that a case of a switch must be
// terminated somehow unless you want to carry on executing the next case
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What is printed by the program?
/*
int main() {
    const unsigned int max = 10;
    for (unsigned int i = max; i >= 0; --i) {
        std::cout << i << std::endl;
    }
}*/
// Answer: All ints in descending order
// Description: When i becomes 0 and we execute --i, we get the 
// biggest possitive int, because i is unsigned
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What function is called in the program?
/*
double sum(float a, float b) {
    return a + b;
}

float sum(float a, float b) {
    return a + b;
}
int main() {
    sum(5.0f, 10.0f);
}*/
// Answer: Compile error
// Description: Cannot overload functions distinguished by
// return type alone
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed?
/*
void printSum (float a, float b, float c);
void printSum (float a, float b, float) {
    std::cout << a + b << std::endl;
}

int main() {
    printSum(5.0f, 10.0f, 20.0f);
}*/
// Answer: 15
// Description: 
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed?
/*
void printSum (float a, float b, float c);
void printSum (float a, float b, float c) {
    std::cout << a + b << std::endl;
}

int main() {
    printSum(5.0f, 10.0f, 20.0f);
}*/
// Answer: 15
// Description: 
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What function is called?
/*
void print (double);
void print (long);

int main() {
    print(5);
}*/
// Answer: Compilation error
// Description: More than one instance of overloaded print function
// matches the argument list
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed?
/*
void print(int a, int b = 5, int c) {
    std::cout << a + b << std::endl;
}

int main() {
    print(10, 20, 30);
}*/
// Answer: Compilation error
// Description: Default arguments may be provided for 
// trailing arguments only
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed?
/*
int foo(int x, int y = x) { 
    return x + y; 
} 

int main() { 
    std::cout << foo(2) << std::endl; 
}*/
// Answer: Compilation error
// Description: Parameters of a function can not be used
// in default argument expressions
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Question: What value gets printed?
int sum(int *a, int *b) {
    return *a + *b;
}

int main() {
    const int num1 = 1;
    const int num2 = 2;
    const int * const pNum1 = &num1;
    int (*sumPtr) (const int*, const int *) = sum;
    sumPtr(pNum1, &num2);
}
// Answer: Compilation error
// Description: Parameters of a function can not be used
// in default argument expressions
//////////////////////////////////////////////////////////////////////////
